Previous: Function Bindings, Up: Variable Bindings [Contents][Index]
These forms create local macros and “symbol macros”.
This form is analogous to cl-flet, but for
macros instead of functions. Each binding is a
list of the same form as the arguments to
cl-defmacro (i.e., a macro name, argument list,
and macro-expander forms). The macro is defined accordingly
for use within the body of the cl-macrolet.
Because of the nature of macros, cl-macrolet
is always lexically scoped. The cl-macrolet
binding will affect only calls that appear physically within
the body forms, possibly after expansion of other
macros in the body.
This form creates symbol macros, which are macros that look like variable references rather than function calls. Each binding is a list ‘(var expansion)’; any reference to var within the body forms is replaced by expansion.
(setq bar '(5 . 9))
(cl-symbol-macrolet ((foo (car bar)))
(cl-incf foo))
bar
⇒ (6 . 9)
A setq of a symbol macro is treated the same
as a setf. I.e., (setq foo 4) in
the above would be equivalent to (setf foo 4),
which in turn expands to (setf (car bar) 4).
Likewise, a let or let* binding
a symbol macro is treated like a cl-letf or
cl-letf*. This differs from true Common Lisp,
where the rules of lexical scoping cause a let
binding to shadow a symbol-macrolet binding. In
this package, such shadowing does not occur, even when
lexical-binding is t. (This
behavior predates the addition of lexical binding to Emacs
Lisp, and may change in future to respect
lexical-binding.) At present in this package,
only lexical-let and lexical-let*
will shadow a symbol macro. See Obsolete
Lexical Binding.
There is no analogue of defmacro for symbol
macros; all symbol macros are local. A typical use of
cl-symbol-macrolet is in the expansion of
another macro:
(cl-defmacro my-dolist ((x list) &rest body)
(let ((var (cl-gensym)))
(list 'cl-loop 'for var 'on list 'do
(cl-list* 'cl-symbol-macrolet
(list (list x (list 'car var)))
body))))
(setq mylist '(1 2 3 4))
(my-dolist (x mylist) (cl-incf x))
mylist
⇒ (2 3 4 5)
In this example, the my-dolist macro is
similar to dolist (see Iteration) except that the
variable x becomes a true reference onto the
elements of the list. The my-dolist call shown
here expands to
(cl-loop for G1234 on mylist do
(cl-symbol-macrolet ((x (car G1234)))
(cl-incf x)))
which in turn expands to
(cl-loop for G1234 on mylist do (cl-incf (car G1234)))
See Loop
Facility, for a description of the cl-loop
macro. This package defines a nonstandard in-ref
loop clause that works much like my-dolist.
Previous: Function Bindings, Up: Variable Bindings [Contents][Index]